#include "compiler/planner.h"

std::unique_ptr<Execution::PlanNode> Planner::createPlan(const std::unique_ptr<AST::Statement>& stmt) {
    if (dynamic_cast<AST::CreateTableStmt*>(stmt.get())) {
        return createCreateTablePlan(*static_cast<AST::CreateTableStmt*>(stmt.get()));
    }
    else if (dynamic_cast<AST::InsertStmt*>(stmt.get())) {
        return createInsertPlan(*static_cast<AST::InsertStmt*>(stmt.get()));
    }
    else if (dynamic_cast<AST::SelectStmt*>(stmt.get())) {
        return createSelectPlan(*static_cast<AST::SelectStmt*>(stmt.get()));
    }
    else if (dynamic_cast<AST::DeleteStmt*>(stmt.get())) {
        return createDeletePlan(*static_cast<AST::DeleteStmt*>(stmt.get()));
    }
    // Add handling for UpdateStmt in createPlan method
    else if (dynamic_cast<AST::UpdateStmt*>(stmt.get())) {
        return createUpdatePlan(*static_cast<AST::UpdateStmt*>(stmt.get()));
    }
    
    return nullptr;
}

// Move createUpdatePlan() method here as a member function implementation of Planner class
std::unique_ptr<Execution::PlanNode> Planner::createUpdatePlan(const AST::UpdateStmt& stmt) {
    auto plan = std::make_unique<Execution::UpdatePlan>();
    plan->tableName = stmt.tableName;

    // 处理列值对
    for (const auto& [colName, expr] : stmt.columnValues) {
        plan->columnValues.emplace_back(colName, expr->toString());
    }

    // 处理WHERE条件
    if (stmt.whereClause) {
        plan->filter = expressionToString(*stmt.whereClause);
    }

    return plan;
}

std::unique_ptr<Execution::PlanNode> Planner::createCreateTablePlan(const AST::CreateTableStmt& stmt) {
    auto plan = std::make_unique<Execution::CreateTablePlan>();
    plan->tableName = stmt.tableName;
    plan->columns = stmt.columns;
    return plan;
}

std::unique_ptr<Execution::PlanNode> Planner::createInsertPlan(const AST::InsertStmt& stmt) {
    auto plan = std::make_unique<Execution::InsertPlan>();
    plan->tableName = stmt.tableName;
    plan->columns = stmt.columns;

    for (const auto& value : stmt.values) {
        plan->values.push_back(value->toString());
    }

    return plan;
}

std::unique_ptr<Execution::PlanNode> Planner::createSelectPlan(const AST::SelectStmt& stmt) {
    auto plan = std::make_unique<Execution::SelectPlan>();
    plan->tableName = stmt.tableName;
    plan->columns = stmt.columns;

    if (stmt.whereClause) {
        plan->filter = expressionToString(*stmt.whereClause);
    }

    return plan;
}

std::unique_ptr<Execution::PlanNode> Planner::createDeletePlan(const AST::DeleteStmt& stmt) {
    auto plan = std::make_unique<Execution::DeletePlan>();
    plan->tableName = stmt.tableName;

    if (stmt.whereClause) {
        plan->filter = expressionToString(*stmt.whereClause);
    }

    return plan;
}

std::string Planner::expressionToString(const AST::Expression& expr) {
    return expr.toString();
}